import random
from math import sqrt, pow, exp, log
from models.graph import OneDimensionalGraph,OneDimensionalGraphPeerAttachment,TwoDimensionalGraphCellularModel

def simulateCoverages(number_vertices_total, number_runs, seed=42):
    """
    Creates new random graph for each number of vertices
    Complexity: O(number_vertices_total^2 * number_runs)
    """
    # Set random generator
    random.seed(seed)

    # Perform simulation
    coverages = []
    borders = []
    #for number_vertices in range(1, number_vertices_total + 1):
    for number_vertices in range(number_vertices_total, number_vertices_total + 1):
        # print "processing... number of vertices ==", number_vertices
        fixed_number_coverages = []
        fixed_number_borders = []
        for run in range(number_runs):
            g = TwoDimensionalGraphCellularModel(cellular_radius=1, cross=True)
			#g = OneDimensionalGraph(radius=0.5)
            #g = OneDimensionalGraphPeerAttachment(radius=0.5)
            for n in range(number_vertices):
                g.addRandomVertex()
            fixed_number_coverages.append(g.getCoverage())
            fixed_number_borders.append(len(g.getBorder()))
        coverages.append(fixed_number_coverages)
        borders.append(fixed_number_borders)
    prob_of_return = 0.3405373296
    alpha = 0.687
    print "i\tmean\tconj0.7/mean\tconj/mean\t"
    for i, cov in enumerate(coverages):
        i = number_vertices_total-1
        #print str(i+1) + "\t" + "\t".join(map(str,cov))
        #alpha = 0.7
        conj07 = 0.4 * pow(i+1, 0.7)
        conj = 0.4/0.9*pow(i+1,alpha)
        mean = sum(cov) / float(len(cov))
        print "%d\t%.2f\t%.2f\t%.2f" % (i+1, mean, conj07/mean, conj/mean)

def simulateGraphInstance(number_vertices, seed=42):
    random.seed(seed)
    g = OneDimensionalGraph()
    for n in range(number_vertices):
        g.addRandomVertex()
    return g.getVertices()

def simulatePaths(number_vertices, number_runs, seed=42):
    """
    Simulates evolution of graph: in each run, sequentally adds vertices to graph, one after another
    Output: coverage of graph with particular number of vertices in each run
    Complexity: O(number_vertices_total * number_runs)
    """
    # Set random generator
    random.seed(seed)

    # Perform simulation
    for run in range(number_runs):
        g = OneDimensionalGraph(radius=.5)
        for n in range(number_vertices):
            g.addRandomVertex()
            print "%d\t%d\t%.3f" % (run, n+1, g.getCoverage())
